package joshua.hibernate.dao;


import java.io.Serializable;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;

public class SessionDAO {

	
	public final Session session;
	
	public static SessionDAO newInstatnce() {
		return new SessionDAO();
	}
	
	
	public void closeSession() {
		session.close();
		isSessionClose = true;
	}
	
	
	public void begin() {
		if (isSessionClose) {
			throw new HibernateException("Session had been closed. can't begin new transaction.");
		}
		if (tx != null) {
			throw new HibernateException("An old transaction doesn't commit or rollback, can't begin a new transaction.");
		}
		tx = session.beginTransaction();
		tx.begin();
	}
	
	
	public void commit() {
		if (isSessionClose) {
			throw new HibernateException("Session had been closed. can't commit transaction.");
		}
		if (tx == null) {
			throw new HibernateException("no transaction had been began, can't commit.");
		}
		tx.commit();
		tx = null;
	}
	
	
	public Query createQuery(String hql) {
		return session.createQuery(hql);
	}
	
	
	public <T> Serializable save(T obj) {
		return session.save(obj);
	}
	
	
	public <T> void delete(T obj) {
		session.delete(obj);
	}
	
	
	public void rollback() {
		if (isSessionClose) {
			throw new HibernateException("Session had been closed. can't rollback transaction.");
		}
		if (tx == null) {
			throw new HibernateException("no transaction had been began, can't rollback.");
		}
		tx.rollback();
		tx = null;
	}
	
	
	private static final SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
	private Transaction tx;
	private boolean isSessionClose = false; 
	private SessionDAO(){
		session = sessionFactory.openSession();
		tx = null;
	}
}
